package com.nineclock.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.sms.SmsUtils;
import com.nineclock.common.utils.PhoneNumCheckUtils;
import com.nineclock.system.service.SmsService;
import com.nineclock.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SmsUtils smsUtils;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void sendSmsCode(String mobile, String type) {

        //1.判断参数合法性
        //1.1 判断参数是否为空
        if(StrUtil.isEmpty(mobile) || StrUtil.isEmpty(type)){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //1.2 判断手机号格式是否正确
        if(!PhoneNumCheckUtils.isPhoneLegal(mobile)){
            throw new NcException(ResponseEnum.INVALID_PHONE_NUMBER);
        }

        //2.判断类型，是否是注册场景
        //2.1 如果是注册，那么手机号在表中不能存在
        if(type.equals(SMSConstant.SMS_TYPE_REGISTER)){
            Boolean flag = sysUserService.checkMobileExists(mobile);
            if(flag){
                throw new NcException(ResponseEnum.USER_MOBILE_EXISTS);
            }
        } else {
            //2.1 如果不是注册，那么手机要在表中一定要存在
            Boolean flag = sysUserService.checkMobileExists(mobile);
            if(!flag){
                throw new NcException(ResponseEnum.USER_NOT_REGISTER);
            }
        }

        //3.调用阿里云发送短信
        String code = RandomUtil.randomNumbers(6);
        log.info("验证码：{}" , code);
//        boolean result = smsUtils.sendSms(mobile, code);
//        if(!result){
//            throw new NcException(ResponseEnum.SEND_MESSAGE_ERROR);
//        }

        //4.将短信验证码存入redis，过期时间5分钟
        String redisKey  = getPrefix(type) +  mobile;
        redisTemplate.boundValueOps(redisKey).set(code,5, TimeUnit.MINUTES);

        log.info("成功发送验证码 , {}->{} " , mobile, code);
    }

    /**
     * 根据类型获取redis的key名称
     */
    private String getPrefix(String type){
        switch (type) {
            case SMSConstant.SMS_TYPE_LOGIN:
                return SMSConstant.SMS_LOGIN_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_REGISTER:
                return SMSConstant.SMS_REGISTER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_CHANGE_MANAGER:
                return SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_RESET_PASSWORD:
                return SMSConstant.SMS_RESET_KEY_PREFIX;
            default:
                return null;
        }
    }

    @Override
    public Boolean verifySmsCode(String checkcode, String mobile, String type) {

        //1.获取redisKey
        String redisKey  = getPrefix(type) +  mobile;

        //2.根据redisKey从redis查询code
        String code = (String)redisTemplate.boundValueOps(redisKey).get();

        //3.判断code如果存在且与参数中chcekcode相等则验证成功
        if(!StrUtil.isEmpty(code) && code.equals(checkcode)){
            //验证成功后删除
            redisTemplate.delete(redisKey);
            return true;
        }

        //4.否则失败
        return false;
    }


    @Override
    public void deleteSmsCode(String mobile, String type) {
        String key = getPrefix(type) + mobile;
        redisTemplate.delete(key);
    }
}
